package com.sky.sky_server.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.sky_pojo.dto.DishDTO;
import com.sky.sky_pojo.dto.DishVO;
import com.sky.sky_pojo.entity.Dish;
import com.sky.sky_pojo.entity.DishFlavor;
import com.sky.sky_pojo.entity.DishQueryPage;
import com.sky.sky_pojo.entity.PageResult;
import com.sky.sky_server.mapper.DishFlavorMapper;
import com.sky.sky_server.mapper.DishMapper;
import com.sky.sky_server.mapper.SetmealDishMapper;
import com.sky.sky_server.service.DishService;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class DishServiceImpl implements DishService{

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    /**
     * 添加菜品和口味
     */
    @Transactional // 开启事务
    public int addDishAndFlavor(DishDTO dishDTO) {
        // 向菜品表插入一条数据
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        int disInsertNum = dishMapper.insert(dish);

        // 主键返回
        Long dishId = dish.getId();

        // 向口味表插入多条数据
        if(dishDTO.getFlavors() != null && dishDTO.getFlavors().size() > 0) {
            dishDTO.getFlavors().forEach(flavor -> flavor.setDishId(dishId)); // 设置菜品id
            dishFlavorMapper.insertBatch(dishDTO.getFlavors()); // 批量插入
        }

        return disInsertNum;

    }


    /**
     * 根据分类id查询菜品
     */
    @Override
    public List<Dish> listByCategoryId(Long categoryId) {
        return dishMapper.listByCategoryId(categoryId);
    }


    /**
     * 菜品的分页查询
     */
    @Override
    public PageResult<DishVO> page(DishQueryPage dishQueryPage) {
        log.info("分页查询菜品:{}", dishQueryPage);

        PageHelper.startPage(dishQueryPage.getPage(), dishQueryPage.getPageSize());

        List<DishVO> dishList = dishMapper.pageQuery(dishQueryPage);
        Page<DishVO> dishPage = (Page<DishVO>) dishList;

        List<DishVO> res = dishPage.getResult();
        Long total = dishPage.getTotal();
        dishPage.close();

        return new PageResult<DishVO>(total, res);
    }

    /**
     * 批量删除菜品,删除每条菜品都需要查询一条sql,性能较差
     * 使用deleteDishByIds方法
     */
    @Override
    @Deprecated
    public int deleteDish(List<Long> ids) {
        
        boolean isDelete = false;
        for (Long id : ids) {
            // 如果套餐关系表有该菜品的id,则不能删除
            int count = setmealDishMapper.countByDishId(id);
            if(count > 0)
                continue;
            // 如果菜品的状态为起售，则不能删除
            Dish dish = dishMapper.selectById(id);
            if(dish.getStatus() == 1)
                continue;
            boolean del = dishMapper.deleteById(id) > 0;
            if(del){
                
                // 删除对应的口味
                dishFlavorMapper.deleteByDishId(id);
            }
            isDelete = del | isDelete;
        }
        // 有过有任意删除项则返回1
        if(!isDelete)
            return -1;
        return 1;
        // todo 这里应该用批量删除
        // dishFlavorMapper.deleteByIds(ids);

    }


    /**
     * 批量删除菜品
     */
    @Override
    @Transactional
    public int deleteDishByIds(List<Long> ids) {
        if(ids == null || ids.size() == 0)
            return 1;
        // 批量查询是否有该菜品的套餐
        if(setmealDishMapper.selectByDishIds(ids) > 0)
            return -1;
        // 批量查询菜品的状态
        List<Dish> dishs = dishMapper.selectByDishIds(ids);
        for(Dish dish : dishs){
            if(dish.getStatus() == 1)
                throw new RuntimeException("删除菜品失败");
        }
        // 批量删除菜品
        boolean del = dishMapper.deleteByIds(ids) > 0;
        if(del == false)
            throw new RuntimeException("删除菜品失败");
        // 删除对应的口味
        dishFlavorMapper.deleteByDishIds(ids);

        return 1;
    }


    /**
     * 根据id修改菜品状态
     */
    @Override
    public int updateStatus(Long id, Integer status) {
        if(status == null || id == null)
            return -1;
       Dish dish = new Dish();
       dish.setId(id);dish.setStatus(status);
       return dishMapper.updateById(dish);
    }


    /**
     * 根据菜品id查菜品信息
     */
    @Override
    public DishVO getById(Long dishId) {
        // todo 这里应该加上和order_detail表的联动，那个表里有个name的冗余字段也需要更新，暂时可以不用改，后面涉及到该冗余字段的查询还是回到dish表里查的，并没有用到这个冗余字段
        if(dishId == null)
            return null;
        // 根据菜品id查询菜品信息
        Dish dish = dishMapper.selectById(dishId);
        // 根据菜品id查询对应的口味数据
        List<DishFlavor> dishFlavors = dishFlavorMapper.selectByDishId(dishId);
        // 根据菜品id查询分类信息
        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish, dishVO);
        dishVO.setFlavors(dishFlavors);
        return dishVO;
    }

    /**
     * 根据id查询菜品信息列表
     */
    @Override
    public List<DishVO> listDishVOsByCategoryId(Long categoryId) {
        List<DishVO> dishVOS = dishMapper.selectDishVOsByCategoryId(categoryId);
        if(dishVOS == null || dishVOS.size() <= 0){
            return null;
        }
        List<Long> dishIds = dishVOS.stream().map(s -> s.getId()).collect(Collectors.toList());
        List<DishFlavor> dishFlavors = dishFlavorMapper.selectByDishIds(dishIds);
        Map<Long, List<DishFlavor>> dishFlavorMap = dishFlavors.stream().collect(Collectors.groupingBy(DishFlavor::getDishId));
        dishVOS.forEach(dishVO -> {
            dishVO.setFlavors(dishFlavorMap.getOrDefault(dishVO.getId(), new ArrayList<>()));
        });
        return dishVOS;
    }


    /**
     * 修改菜品
     */
    @Override
    @Transactional
    public int update(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        int res = dishMapper.updateById(dish);
        if (res != 0) {
            // 删除对应的口味
            dishFlavorMapper.deleteByDishId(dish.getId());
            // 添加新的口味
            List<DishFlavor> dishFlavors = dishDTO.getFlavors();
            if(dishFlavors != null && dishFlavors.size() != 0) {
                for (DishFlavor dishFlavor : dishFlavors) {
                    dishFlavor.setDishId(dish.getId());
                }
                dishFlavorMapper.insertBatch(dishFlavors);
            }
        }
        return res;
    }


    
}
